/****************************************************************************/
/* File: scs-mouse.cpp                                                      */
/* Desc: Implementation file for the input mouse type                       */
/* Created: 2014-11-12                                                      */
/* Revised: 2014-11-16                                                      */
/* Authors: Sterling P. de Mille                                            */
/****************************************************************************/

// specification file
#include "scs-mouse.h"

SCSmouse* SCSmouse::m_pkSingleton = NULL;

SCSmouse::SCSmouse ()
{
	assert(!m_pkSingleton);
	m_pkSingleton = this;

	m_iRelativeMotion = SCS_FALSE;
	Init();
}

SCSmouse::~SCSmouse ()
{
	assert(m_pkSingleton);
	m_pkSingleton = NULL;

	m_iRelativeMotion = SCS_FALSE;
	m_kPreviousState.iButtonStates = m_kCurrentState.iButtonStates = 0;
	m_kPreviousState.iPosX = m_kCurrentState.iPosX = 0;
	m_kPreviousState.iPosY = m_kCurrentState.iPosY = 0;
}

SCSint SCSmouse::GetX ()
{
	return m_kCurrentState.iPosX;
}

SCSint SCSmouse::GetY ()
{
	return m_kCurrentState.iPosY;
}

SCSint SCSmouse::DeltaX ()
{
	return (m_kCurrentState.iPosX - m_kPreviousState.iPosX);
}

SCSint SCSmouse::DeltaY ()
{
	return (m_kCurrentState.iPosY - m_kPreviousState.iPosY);
}

void SCSmouse::ScrollUp ()
{
	m_kCurrentState.iScrollValue += 1;
}

void SCSmouse::ScrollDown ()
{
	m_kCurrentState.iScrollValue -= 1;
}

SCSint SCSmouse::ScrollValue ()
{
	return m_kCurrentState.iScrollValue;
}

SCSint SCSmouse::SdlButton (SCSint iButton)
{
	switch(iButton) {
	case BUTTON_LEFT:
		return SDL_BUTTON_LEFT;
	case BUTTON_RIGHT:
		return SDL_BUTTON_RIGHT;
	case BUTTON_MIDDLE:
		return SDL_BUTTON_MIDDLE;
	default:
		return SDL_BUTTON_LEFT;
	}
}

SCSbool SCSmouse::ButtonPressed (SCSint iButton)
{
	SCSint iSdlButton = SdlButton(iButton);
	SCSint iCurrentState = (m_kCurrentState.iButtonStates & SDL_BUTTON(iSdlButton));
	SCSint iPreviousState = (m_kPreviousState.iButtonStates & SDL_BUTTON(iSdlButton));
	return (iCurrentState && !iPreviousState);
}

SCSbool SCSmouse::ButtonReleased (SCSint iButton)
{
	SCSint iSdlButton = SdlButton(iButton);
	SCSint iCurrentState = (m_kCurrentState.iButtonStates & SDL_BUTTON(iSdlButton));
	SCSint iPreviousState = (m_kPreviousState.iButtonStates & SDL_BUTTON(iSdlButton));
	return (!iCurrentState && iPreviousState);
}

SCSbool SCSmouse::ButtonDown (SCSint iButton)
{
	SCSint iSdlButton = SdlButton(iButton);
	SCSint iCurrentState = (m_kCurrentState.iButtonStates & SDL_BUTTON(iSdlButton));
	return (iCurrentState != 0);
}

SCSbool SCSmouse::ButtonUp (SCSint iButton)
{
	SCSint iSdlButton = SdlButton(iButton);
	SCSint iCurrentState = (m_kCurrentState.iButtonStates & SDL_BUTTON(iSdlButton));
	return (iCurrentState == 0);
}

void SCSmouse::Init ()
{
	m_kCurrentState.iButtonStates = SDL_GetMouseState(&m_kCurrentState.iPosX, &m_kCurrentState.iPosY);
	m_kPreviousState.iButtonStates = m_kCurrentState.iButtonStates;
	m_kPreviousState.iPosX = m_kCurrentState.iPosX;
	m_kPreviousState.iPosY = m_kCurrentState.iPosY;
	m_kPreviousState.iScrollValue = m_kCurrentState.iScrollValue = 0;
}

void SCSmouse::Update ()
{
	m_kPreviousState.iButtonStates = m_kCurrentState.iButtonStates;
	m_kPreviousState.iPosX = m_kCurrentState.iPosX;
	m_kPreviousState.iPosY = m_kCurrentState.iPosY;
	m_kPreviousState.iScrollValue = m_kCurrentState.iScrollValue = 0;
	m_kCurrentState.iButtonStates = SDL_GetMouseState(&m_kCurrentState.iPosX, &m_kCurrentState.iPosY);
}

SCSstring SCSmouse::GetLabel (SCSint iEvent)
{
    const static SCSstring LABELS [] = {
        "MOVE LEFT",
        "MOVE RIGHT",
        "MOVE UP",
        "MOVE DOWN",
        "SCROLL UP",
        "SCROLL DOWN",
        "BUTTON LEFT",
        "BUTTON MIDDLE",
        "BUTTON RIGHT",
    };
    return LABELS[iEvent];
}

SCSmouse* SCSmouse::Singleton ()
{
	return m_pkSingleton;
}
